/**
 * Copyright (c) 2020 - present, Inspur Genersoft Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import { PaginationPropsType } from '../pagination.props';
import { ref, Ref } from 'vue';
import { PageInfo, UsePages } from './types';

export function usePages(props: PaginationPropsType): UsePages {
    const pages: Ref<PageInfo[]> = ref([]);

    /**
     * Given the position in the sequence of pagination links [i],
     * figure out what page number corresponds to that position.
     */
    function calculatePageNumber(pageIndex: number, currentPage: number, paginationRange: number, totalPages: number) {
        const halfWay = Math.ceil(paginationRange / 2);
        if (pageIndex === paginationRange) {
            return totalPages;
        }
        if (pageIndex === 1) {
            return pageIndex;
        }
        if (paginationRange < totalPages) {
            if (totalPages - halfWay < currentPage) {
                return totalPages - paginationRange + pageIndex;
            }
            if (halfWay < currentPage) {
                return currentPage - halfWay + pageIndex;
            }
            return pageIndex;
        }
        return pageIndex;
    }

    /**
     * Returns an array of Page objects to use in the pagination controls.
     */
    function updatePages(currentPage: number, itemsPerPage: number, totalItems: number, paginationRange: number) {
        const pageInfos: PageInfo[] = [];
        const totalPages = Math.ceil(totalItems / itemsPerPage);
        const halfWay = Math.ceil(paginationRange / 2);

        const isStart = currentPage <= halfWay;
        const isEnd = totalPages - halfWay < currentPage;
        const isMiddle = !isStart && !isEnd;

        const shouldShowEllipses = paginationRange < totalPages;
        let pageIndex = 1;

        while (pageIndex <= totalPages && pageIndex <= paginationRange) {
            const pageNumber = calculatePageNumber(pageIndex, currentPage, paginationRange, totalPages);
            const openingEllipsesNeeded = pageIndex === 2 && (isMiddle || isEnd);
            const closingEllipsesNeeded = pageIndex === paginationRange - 1 && (isMiddle || isStart);
            const label = shouldShowEllipses && (openingEllipsesNeeded || closingEllipsesNeeded) ? '...' : '' + pageNumber;
            pageInfos.push({ label, value: pageNumber });
            pageIndex++;
        }
        pages.value = pageInfos;
    }

    return { pages, updatePages };
}
